<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="tutorial.css">
<TITLE>
Using a Demon
</TITLE>
</HEAD>
<BODY >
<A HREF="tutorial104.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="tutorial098.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="tutorial106.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc209">14.7</A>&nbsp;&nbsp;Using a Demon</H2>
<A NAME="@default378"></A>
Every time the relevant variable bounds change, the delayed ge/2 goal
wakes up and (as long as there are still two variables) a new,
identical goal gets delayed.
To better support this situation, ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> provides a special type
of predicate, called a <B>demon</B>.
A predicate is turned into a
<A NAME="@default379"></A>
demon by annotating it with a
<A HREF="../bips/kernel/compiler/demon-1.html"><B>demon/1</B></A><A NAME="@default380"></A>
declaration.
A demon goal differs from a normal goal only in its behaviour on
waking. While a normal goal disappears from the resolvent when it is
woken, the demon remains in the resolvent.
Declaratively, this corresponds to an implicit recursive call in
the body of each demon clause.
Or, in other words, the demon goal forks into one goal that remains in the
suspended part of the resolvent, and an identical one
that gets scheduled for execution.<BR>
<BR>
With a demon, our above example can be done more
efficiently. One complication arises, however. Since the goal
implicitly re-suspends, it now has to be explicitly killed when
it is no longer needed. The easiest way to achieve this is to
let it have a handle to itself (its `suspension') in one of its arguments.
This can then be used to kill the suspension when required:

	<TABLE CELLPADDING=10>
<TR><TD BGCOLOR="#CCCCFF">
	<BLOCKQUOTE CLASS="quote"><PRE>
ge(X, Y) :-
        suspend(ge(X,Y,MySusp), 0, [X-&gt;ic:max, Y-&gt;ic:min], MySusp),
        ge(X, Y, MySusp).

:- demon ge/3.
ge(X, Y, MySusp) :-
        get_bounds(X, _, XH),
        get_bounds(Y, YL, _),
        ( var(X),var(Y) -&gt;
            true     % implicitly re-suspend
        ;
            kill_suspension(MySusp)
        ),
        X #&gt;= YL,    % impose new bounds
        Y #=&lt; XH.
</PRE></BLOCKQUOTE></TD>
</TR></TABLE>
We have used the new primitives suspend/4 and kill_suspension/1.<BR>
<BR>
<HR>
<A HREF="tutorial104.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="tutorial098.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="tutorial106.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
